﻿/*-------------------------------------------------------------------------
* 命名空间: ScreenCapture.Base.Settings/PropertyStore
* 类       名: PropertyStore
* 功      能:  TD
* 时      间:  2023/12/5 10:41:10
* 版      本:  V1.0
* 作      者:  Fioman
* 格      言:  Talk is cheap,show me the code ^_^
*-------------------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;

namespace ScreenCapture.Base.Settings
{
    /// <summary>
    /// 这就是这个属性字典,键是属性值,值是属性对应的值,这么设计的目的是什么呢?
    /// 这个类设计提供了一种通用的机制来存储和获取属性值.通过使用Dictionary来存储属性值.
    /// 我们可以根据属性名称快速获取对应的值,而不需要为每一个属性定义一个单独的字段.这样可以简化代码
    /// 并提高代码的可维护性.另外,通过继承NotifyPropertyChanged类,该类还可以通知属性更改事件,
    /// 使得其他的类能够监听属性的变量并作出相应的响应.
    /// 总之,PropertyStore类是一个通用的属性存储和访问机制,它提供了一种简单,灵活的方式来管理属性值,
    /// 并允许其他类监听属性更改事件.
    /// </summary>
    public class PropertyStore : NotifyPropertyChanged
    {
        private readonly Dictionary<string, object> _dictionary = new Dictionary<string, object>();

        /// <summary>
        /// 属性获取方法Get. 如果不提供任何的参数(属性)就返回null,这里第一个参数是干嘛的
        /// 第一个参数是用来提供默认类型的,如果在字典中找不到这个属性名称,就返回第一个参数提供的默认类型值.
        /// 如果不提供,其实就是泛型参数T的类型,但是也是可以提供的.
        /// 注意基类中的Get方法,基类NotifyPropertyChanged没有Get方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Default"></param>
        /// <param name="PropertyName"></param>
        /// <returns></returns>
        protected T Get<T>(T Default = default, [CallerMemberName] string PropertyName = "")
        {
            lock (_dictionary)
            {
                if (_dictionary.TryGetValue(PropertyName, out var obj) && obj is T val)
                    return val;
            }
            return Default;
        }

        /// <summary>
        /// 属性设置的时候调用这个方法,注意基类重点额Set方法为
        /// protected bool Set<T>(ref T Field, T Value,[CallerMemberName] string PropertyName= null)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Value"></param>
        /// <param name="PropertyName"></param>
        protected void Set<T>(T Value, [CallerMemberName] string PropertyName = "")
        {
            lock (_dictionary)
            {
                _dictionary[PropertyName] = Value;
            }
            OnPropertyChanged(PropertyName);
        }
    }
}
